﻿using System;
using System.IO;

namespace tuimg.structs
{
    using tuimg.helpers;

    internal struct struct_32bit_color
    {
        internal byte B;
        internal byte G;
        internal byte R;
        internal byte A;

        internal struct_32bit_color(Stream sr)
        {
            B = helper.Readbyte(sr);
            G = helper.Readbyte(sr);
            R = helper.Readbyte(sr);
            A = helper.Readbyte(sr);
        }
        internal struct_32bit_color(byte r, byte g, byte b, byte a)
        {
            R = r; G=g; B = b;A = a;
        }
    }

    internal struct struct_8bit_color
    {
        internal byte color;
        internal struct_8bit_color(Stream sr)
        {
            color = (byte)sr.ReadByte();
        }
        internal struct_8bit_color(byte r, byte g, byte b)
        {
            color = (byte)((b << 6) | (g << 3) | r);
        }
        //2
        internal byte B { get {return (byte)(color >> 6); } } 
        //3
        internal byte G { get { return (byte)((color >> 3) & 0b111); } }
        //3
        internal byte R { get { return (byte)(color & 0b111); } }
        internal struct_8bit_color(struct_16bit_color _color)
        {
            color = (byte)((byte)((_color.B / 8) << 6) | (byte)((_color.G / 8) << 3) | (byte)(_color.R / 4));
        }
        internal struct_8bit_color(struct_24bit_color _color)
        {
            color = (byte)((byte)((_color.B / 0x40) << 6) | (byte)((_color.G / 0x20) << 3) | (byte)(_color.R / 0x20));
        }
        internal struct_8bit_color(struct_32bit_color _color)
        {
            color = (byte)((byte)((_color.B / 0x40) << 6) | (byte)((_color.G / 0x20) << 3) | (byte)(_color.R / 0x20));
        }
    }
    internal struct struct_16bit_color
    {
        internal byte color1;
        internal byte color2;
        internal struct_16bit_color(Stream sr)
        {
            color1 = (byte)sr.ReadByte();
            color2 = (byte)sr.ReadByte();
        }
        internal struct_16bit_color(byte r, byte g, byte b)
        {
            color1 = (byte)((b << 3) | (g >> 3));
            color2 = (byte)((b << 5) | r);
        }
        // 5
        internal byte B { get { return (byte)(color1 >> 3); } }
        // 6
        internal byte G { get { return (byte)((byte)((color1 << 3)|(color2 >> 5))& 0b11111); } }
        // 5
        internal byte R { get { return (byte)(color2 & 0b11111); } }

        internal struct_16bit_color(struct_32bit_color color)
        {
            var colorg = color.G / 4;
            color1 = (byte)((byte)(color.B / 8) << 3| (colorg >> 3));
            color2 = (byte)((byte)(colorg << 5) | (color.R / 8));
        }
        internal struct_16bit_color(struct_24bit_color color)
        {
            var colorg = color.G / 4;
            color1 = (byte)((byte)(color.B / 8) << 3 | (colorg >> 3));
            color2 = (byte)((byte)(colorg << 5) | (color.R / 8));
        }
        internal struct_16bit_color(struct_8bit_color color)
        {
            var colorg = color.G * 8;
            color1 = (byte)((byte)(color.B*8) << 3 | (colorg >> 3));
            color2 = (byte)((byte)(colorg << 5) | (color.R *4));
        }
    }
    internal struct struct_24bit_color
    {
        internal byte R;
        internal byte G;
        internal byte B;
        internal struct_24bit_color(Stream sr)
        {
            B = (byte)sr.ReadByte();
            G = (byte)sr.ReadByte();
            R = (byte)sr.ReadByte();
        }
        internal struct_24bit_color(byte r, byte g, byte b)
        {
            R = r;
            G = g;
            B = b;
        }
        internal struct_24bit_color(byte r, byte g, byte b, byte a, byte r2, byte g2, byte b2)
        {
            B = helper.blend_color(b, b2, a);
            G = helper.blend_color(g, g2, a);
            R = helper.blend_color(r, r2, a);
        }
        internal struct_24bit_color(struct_32bit_color color) :this(color.R, color.G, color.B, color.A, 0, 0, 0)
        {
        }
        internal struct_24bit_color(struct_32bit_color color, byte r2, byte g2, byte b2) : this(color.R, color.G, color.B, color.A, r2, g2, b2)
        {
        }
        internal struct_24bit_color(struct_32bit_color color, struct_24bit_color background) : this(color.R, color.G, color.B, color.A, background.R, background.G, background.B)
        {
        }
        internal struct_24bit_color(struct_8bit_color color)
        {
            B = (byte)(color.B * 0x40);
            G = (byte)(color.G * 0x20);
            R = (byte)(color.R * 0x20);
        }
        internal struct_24bit_color(struct_16bit_color color)
        {
            B = (byte)(color.B * 8);
            G = (byte)(color.G * 4);
            R = (byte)(color.R * 8);
        }
    }
}
